package org.example.mybatis.Mapper;

import org.apache.ibatis.annotations.*;
import org.example.mybatis.Dao.UserInfo;

import java.util.List;

@Mapper
public interface UserInfoMapper {

    @Select("select * from user_info")
    List<UserInfo> userInfo();

    //使用参数查询
    @Select("select * from user_info where id=1")
    UserInfo userInfoById();

    /**
     * 在查询的时候发现deleteFlag createTime updateTime这些以小驼峰命名的变量并没与够附上值
     * 这时因为mysql中是以下划线来命名变量的，和java的标准不一样，那么为了解决这个问题就可以使用
     */
    //1，结果映射@Result ,可以起别名，这样机可以使用ResultMap来重复利用了
    @Results(id = "baseMap", value = {
            @Result(column = "delete_flag", property = "deleteFlag"),
            @Result(column = "create_time", property = "createTime"),
            @Result(column = "update_time", property = "updateTime")
    })
    @Select("select id,userName,passWord,age,gender,phone,delete_flag,create_time,update_time" +
            " from user_info")
    List<UserInfo> selectAllByRe();

    @Select("select *" +
            " from user_info")
    @ResultMap(value = "baseMap")
    List<UserInfo> selectAllByRe2();

    //2。取别名
    @Select("select id,userName,passWord,age,gender,phone,delete_flag as deleteFlag," +
            "create_time as createTime,update_time as updateTime" +
            " from user_info")
    List<UserInfo> selectAllByNickName();

    //3.修改配置文件 开启驼峰命名 最简单
    //mybatis.configuration.map-underscore-to-camel-case=true
    @Select("select * from user_info")
    List<UserInfo> selectAllByYml();

    //使用传入的参数来查询 只有一个参数，名字对不上 也无所谓
    @ResultMap(value = "baseMap")
    @Select("select * from user_info where id = #{id}")
    UserInfo userInfoById1(int id);

    //使用多个参数来查询 名字需要对应起来
    @Select("select * from user_info where id=#{id} and userName=#{name}")
    List<UserInfo> userInfoById2(String name, int id);

    //是用@param来进行多个参数的查询
    @Select("select * from user_info where id=#{id} and userName=#{username}")
    List<UserInfo> userInfoById3(@Param("username") String name, @Param("id") Integer id);

    /**
     * #{}和${}的区别
     * ${}是即时sql，他对sql语句是直接编译的，会有sql注入的问题
     * #{}是预编译sql，在编译之后会将这个sql语句缓存起来，下次再次执行的话将参数作为字符串来填充到占位符？
     * 为了避免sql注入的问题，在使用${}时要对参数进行判断
     * 能不要$就不用，用的话就要考虑sql注入的问题
     * ---
     * 1）#{}是预编译处理，$ {}是字符串替换。
     * 2）mybatis在处理#{}时，会将sql中的#{}替换为?号，调用PreparedStatement的set方法来赋值；mybatis在处理 $ { } 时，就是把 ${ } 替换成变量的值。
     * 3）使用 #{} 可以有效的防止SQL注入，提高系统安全性。
     */
    @Select("select * from user_info where userName = '${userName}'")
    List<UserInfo> userInfoById4(String userName);

    //${}的使用
    //模糊查询
    @Select("select * from user_info where userName like '%${userName}%'")
    List<UserInfo> userInfoById5(String userName);

    //排序查询
    @Select("select * from user_info order by id ${sort}")
    List<UserInfo> selectAllBySort(String sort);

    //使用#会因为username是字符串而会错误，但是也能预编译的方式来解决这个问题 使用concat来拼接字符串
    @Select("select * from user_info where userName like concat('%',#{name},'%')")
    List<UserInfo> selectAllByName(String name);

    //Insert 插入
    @Insert("insert into user_info (userName,passWord,age,gender,phone)" +
            " values (#{userName},#{passWord},#{age},#{gender},#{phone});")
    int insert(UserInfo userInfo);

    //如果要得这个自增id，需要使用Option这个注解
    @Options(useGeneratedKeys = true, keyProperty = "id")
    @Insert("insert into user_info (userName,passWord,age,gender,phone)" +
            "values (#{UserInfo.userName},#{UserInfo.passWord},#{UserInfo.age}," +
            "#{UserInfo.gender},#{UserInfo.phone})")
    int insert1(@Param("UserInfo") UserInfo userInfo);

    //修改
    @Update("update user_info set delete_flag = 1 where id = #{id}")
    int updateDeleteFlag(int id);

    //删除
    @Delete("delete from user_info where id = #{id}")
    int deleteById(int id);

    //配置mybatis日志打印 配置之后会有==>这个代表的是mybatis输入<==这个是输出
//    mybatis:
//    configuration: #配置打印MyBatis⽇志
//    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


    @SelectProvider(type = UserSqlProvider.class, method = "findActiveUsersByName")
    List<UserInfo> findActiveUsersByName(@Param("name") String name);


}



